package repositorio;

import basicas.Assunto;
import dao.ConexaoBanco;
import static dao.ConexaoBanco.getConexao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import model.EstatisticasIndividuaisDetalhe;
import pergunta.Pergunta;

/**
 *
 * @author Diego
 */
public class PerguntasRepositorio extends ConexaoBanco {

    private static int id = 0;
    private static int idTema = 0;

    public boolean inserirPergunta(Pergunta p) {
        PreparedStatement state = null;
        Connection conexao = ConexaoBanco.getConexao();
        PreparedStatement resposta = null;
        boolean inseriu = false;

        this.id = atualizarIdPergunta();
        try {
            p.setIdPergunta(++id);
            conexao.setAutoCommit(false);
            state = conexao.prepareStatement("INSERT INTO pergunta(pergunta_id,textoDaPergunta,letraA,letraB"
                    + ",letraC,letraD,letraE,assunto,dificuldade) VALUES (?,?,?,?,?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS);

            resposta = conexao.prepareStatement("INSERT INTO resposta(id_resposta,reposta) VALUES"
                    + "(?,?)", Statement.RETURN_GENERATED_KEYS);

            //insercao das perguntas
            state.setInt(1, p.getId_pergunta());
            state.setString(2, p.getTexto());
            state.setString(3, p.getLetraA());
            state.setString(4, p.getLetraB());
            state.setString(5, p.getLetraC());
            state.setString(6, p.getLetraD());
            state.setString(7, p.getLetraE());
            state.setInt(8, p.getId_tema());
            state.setInt(9, p.getDificuldade());

            //insercao das respostas
            resposta.setInt(1, p.getId_pergunta());
            resposta.setString(2, p.getCorreta());

            state.executeUpdate();
            resposta.executeUpdate();
            conexao.commit();
            inseriu = true;
        } catch (SQLException ex) {
            System.out.println("Erro na insercao de Pergunta");
            inseriu = false;
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return inseriu;

    }

    public void inserirTema(String tema) {
        PreparedStatement state = null;
        Connection conexao = getConexao();

        this.idTema = atualizarIdTema();
        try {
            conexao.setAutoCommit(false);
            /* --------------- diego ---------------- */
//          state = conexao.prepareStatement("INSERT INTO temas(tema_id,nome) VALUES(?,?)",Statement.RETURN_GENERATED_KEYS);
            //              state.setInt(1,++idTema);
            //            state.setString(2,tema);
/* ------------------------diego ---------------- */
            /* ------------------ello---------------------------*/
            state = conexao.prepareStatement("INSERT INTO temas(nome) VALUES(?)", Statement.RETURN_GENERATED_KEYS);
            //state.setInt(1,idTema++);
            state.setString(1, tema);
            /* ------------------ello---------------------------*/
            state.executeUpdate();
            conexao.commit();
        } catch (SQLException ex) {
            System.out.println("Erro ao inserir tema: " + tema);
            try {
                conexao.rollback();
            } catch (SQLException ex1) {
                Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex1);
                System.out.println("Erro no Rollback!");
            }
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public List<String> atualizarTemas() {
        Connection conexao = dao.ConexaoBanco.getConexao();
        ResultSet rs = null;
        PreparedStatement state = null;
        String texto = "";
        List<String> retorno = new ArrayList();
        try {
            state = conexao.prepareStatement("SELECT * FROM temas;");

            rs = state.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    texto = rs.getString("nome");
                    retorno.add(texto);
                }
            }
        } catch (SQLException ex) {
            System.out.println("Erro na Atualizar Temas");
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }

        return retorno;
    }

    public List<Pergunta> pegaPerguntas(int tema, int dificuldade) {
        List<Pergunta> retorno = new ArrayList<Pergunta>();
        Connection conexao = ConexaoBanco.getConexao();
        PreparedStatement state = null;
        ResultSet resultado = null;

        try {
            state = conexao.prepareStatement("SELECT * FROM pergunta p\n"
                    + "JOIN resposta r ON r.id_resposta = p.pergunta_id\n"
                    + "WHERE assunto = ? AND dificuldade = ?", Statement.RETURN_GENERATED_KEYS);
            state.setInt(1, tema);
            state.setInt(2, dificuldade);
            resultado = state.executeQuery();

            if (resultado != null) {
                while (resultado.next()) {
                    Pergunta p = new Pergunta(resultado.getNString("textoDaPergunta"), resultado.getNString("letraA"), resultado.getNString("letraB"),
                            resultado.getNString("letraC"), resultado.getNString("letraD"), resultado.getNString("letraE"), resultado.getNString("reposta"), tema, dificuldade);
                    p.setIdPergunta(resultado.getInt("pergunta_id"));

                    retorno.add(p);
                }
            }

        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Erro no select");
        }
        return retorno;
    }

    public String pegarTema(int codigoDoTema) {
        String retorno = "";
        Connection conexao = ConexaoBanco.getConexao();
        PreparedStatement state = null;
        ResultSet resultado = null;
        try {
            state = conexao.prepareStatement("SELECT nome FROM temas WHERE tema_id = ?", Statement.RETURN_GENERATED_KEYS);
            state.setInt(1, codigoDoTema);
            resultado = state.executeQuery();

            if (resultado != null) {
                while (resultado.next()) {
                    retorno = resultado.getString("nome");
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }


        return retorno;
    }

    public String pegarResposta(int codigo) {
        String resposta = null;
        Connection conexao = ConexaoBanco.getConexao();
        PreparedStatement state = null;
        ResultSet resultado = null;

        try {
            state = conexao.prepareStatement("SELECT reposta FROM resposta WHERE id_resposta = ?",
                    Statement.RETURN_GENERATED_KEYS);
            state.setInt(1, codigo);
            resultado = state.executeQuery();

            if (resultado != null) {
                while (resultado.next()) {
                    resposta = resultado.getNString("reposta");
                }
            } else {
                System.out.println("O select voltou nulo!");
            }
        } catch (SQLException ex) {
            System.out.println("Exceção no SQL de pegar resposta.");
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }

        return resposta;
    }

    public void atualizarEstatisticas(int codigo, int acertos, int erros, int totalRespondido) {
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;
        if (listarEstatisticas(codigo).isEmpty()) {
            try {
                state = conexao.prepareStatement("INSERT INTO estatisticasindividuais (id_user, respostasCertas, respostasErradas,  totalRespostas)"
                        + "VALUES (?,?,?,?)", Statement.RETURN_GENERATED_KEYS);
                state.setInt(1, codigo);
                state.setInt(2, acertos);
                state.setInt(3, erros);
                state.setInt(4, totalRespondido);

                state.executeUpdate();
            } catch (SQLException ex) {
                Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            try {
                state = conexao.prepareStatement("UPDATE estatisticasIndividuais SET respostasCertas = respostasCertas + ?"
                        + ",respostasErradas = respostasErradas + ?, totalRespostas = totalRespostas + ? where id_user = ?", Statement.RETURN_GENERATED_KEYS);
                state.setInt(1, acertos);
                state.setInt(2, erros);
                state.setInt(3, totalRespondido);
                state.setInt(4, codigo);
                state.executeUpdate();
            } catch (SQLException ex) {
                Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void atualizarRanking(int codigo, int acertos) {
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;
        //Verificar se o usuário já existe no ranking. Se não, ele deve ser criado.
        if (listarRankingUsuario(codigo).isEmpty()) {
            try {
                state = conexao.prepareStatement("INSERT INTO ranking (id_user, Acertos) VALUES (?,?)", Statement.RETURN_GENERATED_KEYS);
                state.setInt(1, codigo);
                state.setInt(2, acertos);

                state.executeUpdate();
            } catch (SQLException ex) {
                Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {

            try {
                state = conexao.prepareStatement("UPDATE ranking SET Acertos = Acertos + ?"
                        + " WHERE id_user = ?", Statement.RETURN_GENERATED_KEYS);
                state.setInt(1, acertos);
                state.setInt(2, codigo);

                state.executeUpdate();
            } catch (SQLException ex) {
                Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public List listarRankingUsuario(int codigo) {
        List retorno = new ArrayList();
        Connection conexao = getConexao();
        PreparedStatement state = null;
        ResultSet resultado = null;
        int aux;
        try {
            state = conexao.prepareStatement("SELECT * FROM ranking WHERE id_user "
                    + " = ?", Statement.RETURN_GENERATED_KEYS);
            state.setInt(1, codigo);
            resultado = state.executeQuery();

            while (resultado.next()) {
                aux = resultado.getInt("Acertos");
                retorno.add(aux);
            }
        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return retorno;
    }

    public List listarEstatisticas(int codigo) {
        List retorno = new ArrayList();
        Connection conexao = getConexao();
        PreparedStatement state = null;
        ResultSet resultado = null;
        int i = 0;
        int aux;
        try {
            state = conexao.prepareStatement("SELECT * FROM estatisticasindividuais WHERE id_user "
                    + " = ?", Statement.RETURN_GENERATED_KEYS);
            state.setInt(1, codigo);
            resultado = state.executeQuery();

            while (resultado.next()) {
                aux = resultado.getInt("respostasCertas");
                retorno.add(aux);
                aux = resultado.getInt("respostasErradas");
                retorno.add(aux);
                aux = resultado.getInt("totalRespostas");
                retorno.add(aux);
            }
        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return retorno;
    }

    public List listarUsuariosDoRanking() {
        List retorno = new ArrayList();
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;

        try {
            state = conexao.prepareStatement("SELECT id_user FROM ranking ORDER BY Acertos DESC");
            resultado = state.executeQuery();

            while (resultado.next()) {
                retorno.add(resultado.getInt("id_user"));
            }

        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return retorno;

    }

    public List listarPosicoesDoRanking() {
        List retorno = new ArrayList();
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;

        try {
            state = conexao.prepareStatement("SELECT Acertos FROM ranking ORDER BY Acertos DESC");
            resultado = state.executeQuery();

            while (resultado.next()) {
                retorno.add(resultado.getInt("Acertos"));
            }

        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return retorno;
    }

    private int atualizarIdPergunta() {
        int id = 0;
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;

        try {
            state = conexao.prepareStatement("SELECT MAX(pergunta_id) pergunta_id from pergunta");
            resultado = state.executeQuery();

            while (resultado.next()) {
                id = resultado.getInt("pergunta_id");
            }
        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }

        return id;
    }

    private int atualizarIdTema() {
        int id = 0;
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;

        try {
            state = conexao.prepareStatement("SELECT MAX(tema_id) tema_id from temas");
            resultado = state.executeQuery();

            while (resultado.next()) {
                id = resultado.getInt("tema_id");
            }
        } catch (SQLException ex) {
            Logger.getLogger(PerguntasRepositorio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return id;
    }

    public void atualizarEstatisticasDetalhadas(List<Pergunta> listaDePerguntasRespondidas, int idUsuario) {
        Connection conexao = getConexao();
        PreparedStatement state = null;
        try {
            conexao.setAutoCommit(false);
            int count = 0;
            for (Pergunta p : listaDePerguntasRespondidas) {
                if (count == 10) {
                    break;
                }
                state = conexao.prepareStatement("INSERT "
                        + "INTO estatisticas_individuais_detalhe (id_usuario,id_pergunta, dificuldade,assunto, acertou)"
                        + "VALUES (?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS);
                state.setInt(1, idUsuario);
                state.setInt(2, p.getId_pergunta());
                state.setInt(3, p.getDificuldade());
                state.setInt(4, p.getId_tema());
                state.setBoolean(5, p.getAcertou());
                state.executeUpdate();
                count++;
            }
            conexao.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public List<Pergunta> obterEstatisticasDetalhadas(int idUsuario) {
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;
        ArrayList<Pergunta> estatisticasDetalhadas = new ArrayList();
        try {
            state = conexao.prepareStatement("SELECT id_usuario, id_pergunta, acertou, dificuldade, assunto "
                    + "FROM estatisticas_individuais_detalhe "
                    + "WHERE id_usuario = ?", Statement.RETURN_GENERATED_KEYS);
            state.setInt(1, idUsuario);

            resultado = state.executeQuery();

            if (resultado != null) {
                while (resultado.next()) {
                    Pergunta pergRespondida = new Pergunta();
                    pergRespondida.setIdPergunta(resultado.getInt("id_pergunta"));
                    pergRespondida.setAcertou(resultado.getBoolean("acertou"));
                    pergRespondida.setDificuldade(resultado.getInt("dificuldade"));
                    pergRespondida.setIdTema(resultado.getInt("assunto"));
                    estatisticasDetalhadas.add(pergRespondida);
                }
            } else {
                System.out.println("O select voltou nulo!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return estatisticasDetalhadas;
    }

    public List listarTemas() throws SQLException {
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;
        ArrayList<Assunto> temas = new ArrayList();

        state = conexao.prepareStatement("SELECT tema_id, nome FROM temas", Statement.RETURN_GENERATED_KEYS);
        resultado = state.executeQuery();
        if (resultado != null) {
            while (resultado.next()) {
                temas.add(new Assunto(resultado.getInt("tema_id"), resultado.getString("nome")));
            }
        }
        return temas;

    }

    public List<EstatisticasIndividuaisDetalhe> listarEstatisticasIndividuaisDetalhe() throws SQLException {
        Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;
        ArrayList<EstatisticasIndividuaisDetalhe> temas = new ArrayList();

        state = conexao.prepareStatement("SELECT * FROM estatisticas_individuais_detalhe", Statement.RETURN_GENERATED_KEYS);
        resultado = state.executeQuery();
        if (resultado != null) {
            while (resultado.next()) {
                temas.add(new EstatisticasIndividuaisDetalhe(resultado.getInt("id"),
                        resultado.getInt("id_pergunta"), resultado.getBoolean("acertou"),
                        resultado.getInt("dificuldade"), resultado.getInt("assunto")));
            }
        }
        return temas;
    }

    public Pergunta pegaPergunta(int idPergunta) {
                Connection conexao = getConexao();
        ResultSet resultado = null;
        PreparedStatement state = null;
       Pergunta pergunta = new Pergunta();
try{
        state = conexao.prepareStatement("SELECT * FROM pergunta WHERE pergunta_id = ?", Statement.RETURN_GENERATED_KEYS);
        state.setInt(1, idPergunta);
        resultado = state.executeQuery();
        if (resultado != null) {
            while (resultado.next()) {
                pergunta = new Pergunta(resultado.getString(2), resultado.getString(3),
                        resultado.getString(4), resultado.getString(5), resultado.getString(6) , resultado.getString(7), pegarResposta(idPergunta),
                        resultado.getInt(8), resultado.getInt(9));
                pergunta.setTema(pegarTema(pergunta.getId_tema()));
            }
        }
        else
        {
            pergunta = null;
        }
}catch(SQLException e)
{
    e.printStackTrace();
}
        return pergunta;
    }
}
